package com.lqzs.businessmanager.utils

import android.accessibilityservice.AccessibilityService
import android.accessibilityservice.GestureDescription
import android.annotation.SuppressLint
import android.content.Context
import android.graphics.Path
import android.graphics.Point
import android.graphics.Rect
import android.os.Build
import android.os.Bundle
import android.util.Log
import android.view.View
import android.view.accessibility.AccessibilityNodeInfo
import android.widget.Button
import android.widget.EditText
import android.widget.ImageView
import android.widget.RelativeLayout
import android.widget.ScrollView
import com.lqzs.businessmanager.Config
import com.lqzs.businessmanager.bean.EleInfo
import com.lqzs.businessmanager.bean.MerChantInfo
import com.lqzs.businessmanager.bean.response.ReviewInfoResponse
import com.lqzs.businessmanager.dao.AccessDao
import com.lqzs.businessmanager.dao.AccessDataBase
import com.lqzs.businessmanager.http.makeRequest
import com.lqzs.businessmanager.http.updateReviewState
import com.lqzs.businessmanager.service.AccessibilitySampleService
import kotlinx.coroutines.delay
import java.util.concurrent.atomic.AtomicInteger


//---------------------------------------------------------------------------------------------------------系统任务--------------------------------------------------------------------------------------------


val TAG: String = "OnClickUtil"
val replayDao = AccessDataBase.getDataBase().replayDao()
/**
 *
 *
 * Gesture手势实现滚动(Android7+)
 * 解决滚动距离不可控制问题
 * @param distanceX 向右滚动为负值 向左滚动为正值
 * @param distanceY 向下滚动为负值 向上滚动为正值
 */
@SuppressLint("ObsoleteSdkInt")
fun scrollByNode(
    service: AccessibilityService,
    nodeInfo: AccessibilityNodeInfo,
    distanceX: Int = 0,
    distanceY: Int = 0
): Boolean {
    if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.N) {
        val rect = Rect()
        nodeInfo.getBoundsInScreen(rect)
        val point = Point((rect.left + rect.right) / 2, (rect.top + rect.bottom) / 2)
        val builder = GestureDescription.Builder()
        val path = Path()
        val startX = point.x.toFloat()
        val startY = point.y.toFloat()
        val endX = startX + distanceX
        val endY = startY + distanceY
        if (startX<0 || startY<0 || endX<0 || endY<0)
            return false

        path.moveTo(startX,startY)
        path.lineTo(endX, endY)
        builder.addStroke(GestureDescription.StrokeDescription(path, 0L, 1000L))
        val gesture = builder.build()
        return service.dispatchGesture(gesture, object : AccessibilityService.GestureResultCallback() {
            override fun onCompleted(gestureDescription: GestureDescription) {
                Log.d(TAG, "startX: $startX endX : $endX  startY:$startY  endY:$endY  scroll ok onCompleted")
            }

            override fun onCancelled(gestureDescription: GestureDescription) {
                Log.d(TAG, "startX: $startX endX : $endX  startY:$startY  endY:$endY  scroll ok onCancelled")
            }
        }, null)
    } else
        return false
}

suspend fun findScrollViews(node: AccessibilityNodeInfo): List<AccessibilityNodeInfo> {
    val scrollViews: MutableList<AccessibilityNodeInfo> = ArrayList()
    // 检查当前节点是否是ScrollView或其子类
    if (node.className == ScrollView::class.java.name) {
        scrollViews.add(node)
    }
    // 获取当前节点的子节点数量
    val childCount = node.childCount
    for (i in 0 until childCount) {
        val child = node.getChild(i)?:continue
        // 递归查找每个子节点
        scrollViews.addAll(findRelativeLayout(child))
    }
    return scrollViews
}

suspend fun findImageViews(node: AccessibilityNodeInfo): List<AccessibilityNodeInfo> {
    val imgViews: MutableList<AccessibilityNodeInfo> = ArrayList()
    // 检查当前节点是否是ScrollView或其子类
    if (node.className == ImageView::class.java.name) {
        imgViews.add(node)
    }
    // 获取当前节点的子节点数量
    val childCount = node.childCount
    for (i in 0 until childCount) {
        val child = node.getChild(i)?:continue
        // 递归查找每个子节点
        imgViews.addAll(findRelativeLayout(child))
    }
    return imgViews
}

fun findRelativeLayout(node: AccessibilityNodeInfo): List<AccessibilityNodeInfo> {
    val relativeLayouts: MutableList<AccessibilityNodeInfo> = ArrayList()
    // 检查当前节点是否是RelativeLayout或其子类
    if (node.className == RelativeLayout::class.java.name) {
        relativeLayouts.add(node)
    }
    // 获取当前节点的子节点数量
    val childCount = node.childCount
    for (i in 0 until childCount) {
        val child = node.getChild(i)?:continue
        // 递归查找每个子节点
        relativeLayouts.addAll(findRelativeLayout(child))
    }
    return relativeLayouts
}

//---------------------------------------------------------------------------------------------------------美团外卖商家--------------------------------------------------------------------------------------------
/**
 * 如果遇到打开声音的弹窗直接进行打开
 */
fun closeSoundDialog(childNodeInfo : AccessibilityNodeInfo,openNodeInfo: AccessibilityNodeInfo?):Boolean{
    val text = childNodeInfo.text
    val viewId = childNodeInfo.viewIdResourceName
    if (text!=null&&text.equals("检测到您的订单响铃时手机声音过小，下次响铃时是否自动打开手机声音") && viewId.contains("id/message")){
        if (openNodeInfo==null)
            return true
        if (openNodeInfo.text.equals("打开") && openNodeInfo.viewIdResourceName.contains("id/turn_on_sound_button")){
            Log.e(TAG,"关闭声音弹窗    ：  ${childNodeInfo.contentDescription}")
            nodeOnClick(openNodeInfo)
            return true
        }
    }
    return false
}

/**
 * 关闭售后提醒弹窗
 */
fun closeAfterSalesDialog(viewNodeInfo : AccessibilityNodeInfo):Boolean{
    val content = viewNodeInfo.contentDescription?: return false
    val className = viewNodeInfo.className?: return false

    if (className == View::class.java.name
        &&content.contains("食安售后提醒")){
        Log.e(TAG,"关闭食安售后提醒弹窗    ：  ${viewNodeInfo.contentDescription}")
        for(i in 0 until viewNodeInfo.childCount){
            val  childNodeInfo = viewNodeInfo.getChild(i) ?: continue
            val nodeContent = childNodeInfo.contentDescription?:continue
            val childClassName = childNodeInfo.className?: continue
            if (childClassName == View::class.java.name
                &&nodeContent.toString().trim() == "关闭"){
                nodeOnClick(childNodeInfo)
                return true
            }
        }
    }
    return false
}

/**
 * 如果遇到弹窗则进行关闭
 */
fun closeDialog(childNodeInfo : AccessibilityNodeInfo):Boolean{
    val viewId = childNodeInfo.viewIdResourceName
    if (viewId!=null && viewId.contains("id/btn_close")){
        Log.e(TAG,"打开声音    ：  ${childNodeInfo.contentDescription}")
        nodeOnClick(childNodeInfo)
        return true
    }
    return false
}

/**
 * 查看信息日期
 */
fun clickTimer(childNodeInfo : AccessibilityNodeInfo):Boolean{
    val content = childNodeInfo.contentDescription?: return false
    val className = childNodeInfo.className?: return false

    if (className == ImageView::class.java.name
        &&content.contains(Config.ONE_MONTH)){
        Log.e(TAG,"点击选择日期    ：  ${childNodeInfo.contentDescription}")
        nodeOnClick(childNodeInfo)
        return true
    }
    return false
}

/**
 * 选择近6个月日期
 */
fun clickTimerSix(childNodeInfo : AccessibilityNodeInfo):Boolean{
    val content = childNodeInfo.contentDescription?: return false
    val className = childNodeInfo.className?: return false

    if (className == View::class.java.name
        &&content.contains(Config.SIX_MONTH)){
        Log.e(TAG,"点击选择日期    ：  ${childNodeInfo.contentDescription}")
        nodeOnClick(childNodeInfo)
        return true
    }
    return false
}

/**
 * 清空所有筛选条件
 */
fun clickSelector(childNodeInfo : AccessibilityNodeInfo):Boolean{
    val content = childNodeInfo.contentDescription?: return false
    val className = childNodeInfo.className?: return false

    if (className == View::class.java.name
        &&content.toString().contains("清除筛选条件 >")){
        nodeOnClick(childNodeInfo)
        return true
    }
    return false
}
/**
 * 点击是否回复   这里是筛选条件的下拉
 */
suspend fun clickReply(childNodeInfo : AccessibilityNodeInfo,str:String):Boolean{
    val content = childNodeInfo.contentDescription?: return false
    val className = childNodeInfo.className?: return false

    if (className == ImageView::class.java.name
        &&content.toString().trim() == str){
        Log.e(TAG,"点击选择是否回复    ：  ${childNodeInfo.contentDescription}")
        nodeOnClick(childNodeInfo)
        return true
    }
    return false
}

/**
 * 选择已回复或者未回复
 */
suspend fun clickViewReplay(childNodeInfo : AccessibilityNodeInfo,str: String):String?{
    val content = childNodeInfo.contentDescription?: return null
    val className = childNodeInfo.className?: return null

    if (className == View::class.java.name
        &&content.toString().trim()==str){
        nodeOnClick(childNodeInfo)
        return str
    }
    return null
}

/**
 * 选择拼好饭
 */
fun clickPinHaoFan(childNodeInfo : AccessibilityNodeInfo):Boolean{
    val content = childNodeInfo.contentDescription ?: return false
    val className = childNodeInfo.className ?: return false
    if (className == View::class.java.name
        &&content.contains(Config.PINHAOFAN)){
        Log.e(TAG,"点击选择拼好饭    ：  ${childNodeInfo.contentDescription}")
        nodeOnClick(childNodeInfo)
        return true
    }
    return false
}

/**
 * 饿了么设置EditText回复内容
 * EditText 会出现软键盘
 * 首先点击别的地方让软键盘消失
 * 再进行点击确认按钮
 */
suspend fun setEleEditText(editText: AccessibilityNodeInfo?,
                           titleNodeInfo: AccessibilityNodeInfo?,
                           buttonNodeInfo: AccessibilityNodeInfo?,
                           reviewInfo: EleInfo?,
                           mAccessService: AccessibilitySampleService,
                           isClickViewReplay: AtomicInteger){
    reviewInfo?:return
    editText?:return
    val className = editText.className ?: return
    if (className == EditText::class.java.name){
        val arguments = Bundle()
        reviewInfo.merchantReplied?.let {
            arguments.putCharSequence(AccessibilityNodeInfo.ACTION_ARGUMENT_SET_TEXT_CHARSEQUENCE, it)
        }
        editText.performAction(AccessibilityNodeInfo.ACTION_SET_TEXT, arguments)
        editText.refresh()
        titleNodeInfo?.let {
            pathOnClick(mAccessService,titleNodeInfo)
        }
        delay(2000)
        buttonNodeInfo?:return
        val viewContent = buttonNodeInfo.text?: return
        val openClassName = buttonNodeInfo.className ?: return
        if (openClassName == Button::class.java.name
            &&viewContent.toString().trim() == "发送"){
            pathOnClick(mAccessService,buttonNodeInfo)
            isClickViewReplay.set(0)
            reviewInfo.merchantReplied?.let {
                val info = makeRequest(updateReviewState(it))
            }
        }

    }
}

suspend fun clickFaSongButton(
    buttonNodeInfo: AccessibilityNodeInfo?,
    reviewInfo: EleInfo,
    mAccessService: AccessibilitySampleService,
    isClickViewReplay: AtomicInteger){
    buttonNodeInfo?:return
    val viewContent = buttonNodeInfo.text?: return
    val openClassName = buttonNodeInfo.className ?: return

    if (openClassName == Button::class.java.name
        &&viewContent.toString().trim() == "发送"){
        pathOnClick(mAccessService,buttonNodeInfo)
        isClickViewReplay.set(0)
        reviewInfo.merchantReplied?.let {
            val info = makeRequest(updateReviewState(it))
        }
    }
}

/**
 * 设置EditText回复内容
 */
suspend fun setEditText(
    editNodeInfo: AccessibilityNodeInfo,
    buttonNodeInfo: AccessibilityNodeInfo?,
    merChantInfo: MerChantInfo,
    mService: AccessibilitySampleService
):Boolean{
    buttonNodeInfo?:return false
    val className = editNodeInfo.className ?: return false
    buttonNodeInfo.className ?: return false

    if (className == EditText::class.java.name){
        val arguments = Bundle()
        merChantInfo.merchantReplied?.let {
            Log.e(TAG, "setEditText1 reviewId ${merChantInfo.reviewId}  content $it")
            arguments.putCharSequence(AccessibilityNodeInfo.ACTION_ARGUMENT_SET_TEXT_CHARSEQUENCE, it)
        }
        editNodeInfo.performAction(AccessibilityNodeInfo.ACTION_SET_TEXT, arguments)
        editNodeInfo.refresh()
        pathOnClick(mService,buttonNodeInfo)
        merChantInfo.reviewId?.let {
            replayDao.deleteByReviewId(it)
            makeRequest(updateReviewState(it))?.let { that ->
                Log.e(TAG, "update response ${that.is_success}")
                return that.is_success
            }
        }
        return false
    }
    return false
}

/**
 * 设置EditText内容
 */
suspend fun setEditText(editNodeInfo: AccessibilityNodeInfo,
                        content: String) : Boolean{
    val className = editNodeInfo.className ?: return false
    if (className == EditText::class.java.name){
        val arguments = Bundle()
        arguments.putCharSequence(AccessibilityNodeInfo.ACTION_ARGUMENT_SET_TEXT_CHARSEQUENCE, content)
        editNodeInfo.performAction(AccessibilityNodeInfo.ACTION_SET_TEXT, arguments)
        editNodeInfo.recycle()
        return true
    }
    return false
}

/**
 * 设置EditText回复内容
 */
suspend fun setEditText(
    childNodeInfo: AccessibilityNodeInfo,
    openNodeInfo: AccessibilityNodeInfo?,
    reviewInfo: ReviewInfoResponse,
    accessDao: AccessDao
):Boolean{
    openNodeInfo?:return false
    val className = childNodeInfo.className ?: return false
    val openClassName = openNodeInfo.className ?: return false
    val viewContent = openNodeInfo.contentDescription?: return false

    if (className == EditText::class.java.name){
        val arguments = Bundle()
        reviewInfo.reply_content?.let {
            arguments.putCharSequence(AccessibilityNodeInfo.ACTION_ARGUMENT_SET_TEXT_CHARSEQUENCE, it)
        }
        childNodeInfo.performAction(AccessibilityNodeInfo.ACTION_SET_TEXT, arguments)
        childNodeInfo.refresh()
        if (openClassName == View::class.java.name
            &&(viewContent.toString().trim() == "回复")){
            nodeOnClick(openNodeInfo)
            openNodeInfo.recycle()
            reviewInfo.review_id?.let {
                Log.e(TAG, "setEditText2: reviewId: ${reviewInfo.review_id}, reviewContent:${reviewInfo.reply_content}" )
                replayDao.deleteByReviewId(it)
                val accessInfo = accessDao.queryForId(it)
                if (accessInfo!=null){
                    accessInfo.merchantReplied = reviewInfo.reply_content
                    accessDao.update(accessInfo)
                }
                val info = makeRequest(updateReviewState(it))
                return true
            }
            return true
        }

    }
    return false
}

/**
 * 是否添加数据库
 */
suspend fun isAddDao(strContent:String):Boolean{
    if (strContent.trim() == "回复"){
        return true
    }
    if (strContent.trim() == "申诉"){
        return true
    }
    if (strContent.trim() == "联系顾客"){
        return true
    }
    if (strContent.trim() == "发券"){
        return true
    }
    if (strContent.trim() == "修改回复"){
        return true
    }
    return false
}

//点击事件
suspend fun pathOnClick(mService: AccessibilitySampleService,nodeInfo: AccessibilityNodeInfo){
    try {
        val rect = Rect()
        nodeInfo.getBoundsInScreen(rect) // 获取相对于屏幕的坐标
        nodeInfo.performAction(AccessibilityNodeInfo.ACTION_FOCUS)
        //路径点击
        val path = Path()
        path.moveTo(((rect.right-rect.left)/2 +rect.left).toFloat(), ((rect.bottom-rect.top)/2+rect.top).toFloat()) // 假设的起始坐标
        path.lineTo(((rect.right-rect.left)/2 +rect.left).toFloat(), ((rect.bottom-rect.top)/2+rect.top).toFloat()) // 点击操作，起点和终点相同
        val stroke = GestureDescription.StrokeDescription(path, 0, 100)
        val gesture = GestureDescription.Builder().addStroke(stroke).build()
        // 执行手势
        mService.dispatchGesture(gesture, object : AccessibilityService.GestureResultCallback() {
            override fun onCompleted(gestureDescription: GestureDescription) {
                nodeOnClick(nodeInfo)
                nodeInfo.refresh()
            }

            override fun onCancelled(gestureDescription: GestureDescription) {
                // 手势取消时调用
            }
        }, null) // 手势执行的 Handler，传 null 表示在主线程执行
    } catch (e: Exception){
        e.printStackTrace()
    }
}

//点击事件
fun nodeOnClick(childNodeInfo : AccessibilityNodeInfo){
    if (childNodeInfo.isClickable){
        childNodeInfo.performAction(AccessibilityNodeInfo.ACTION_FOCUS)
        childNodeInfo.performAction(AccessibilityNodeInfo.ACTION_CLICK)
    }
}